/*原型链继承（共享原型）*/
//父子共用同一个原型链，父子都会对原型影响
//只能继承原型链上的属性

function Father1() {
  this.age = 10;
}
function Son1() { }

Father1.prototype.fatherName = "huang";
Son1.prototype = new Father1()
let son = new Son1(); //son.fatherName === "huang"
Son1.prototype.fatherName = "ZHANG";
let father = new Father1(); //father.fatherName === "ZHANG"

/*构造函数继承*/
//通过call/apply可以向父构造器传参
//只能继承父构造器属性
function Father2(age = 40) {
  this.name = ["huang"];
  this.age = age;
}
function Son2(age) {
  Father2.call(this, age);
}
Father2.prototype.wife = "LI"; //Son.prototype.wife === undefined
Son2.prototype = new Father2()
let son1 = new Son2(18);
son1.name.push("yue"); //son1:{name: ["huang","yue"], age: 18}
let son2 = new Son2(20); //son1:{name: ["huang"], age: 20}

/*圣杯模式*/
//通过中间层,解决共享模型的问题，继承后不影响父级原型
//通过添加属性记住父级原型

function Father3() { }
function Son3() { }
function F() { }
//中间函数拿到父亲的原型
F.prototype = Father3.prototype;
//儿子原型指向f实例，son的原型指向新建的实例对象，该实例对象的原型就是父亲的原型
//实例化了 原型修改无影响
Son3.prototype = new F();
Son3.prototype.constructor = Son3;
let son3 = new Son3();

/* 封装圣杯继承模型 */

function Monther() { }
function Daugther() { }

const inherit = (function () {
  function F() { }
  //利用闭包实现变量私有化
  return (Origin, Target) => {
    F.prototype = Origin.prototype;
    Target.prototype = new F();
    Target.prototype.constructor = Target;
  };
})();
Monther.prototype.name = "母亲名字";
inherit(Monther, Daugther);
Daugther.prototype.name = "女儿的名字"; //不会影响Monther的原型链
let daughter = new Daugther();
let monther = new Monther();
